package com.fastloan.mgt.jx.service.impl;

import com.alibaba.fastjson.JSON;
import com.fastloan.common.model.CheckResult;
import com.fastloan.common.model.CheckResultEnum;
import com.fastloan.mgt.application.base.enums.ApplicationStatusEnum;
import com.fastloan.mgt.application.base.model.Application;
import com.fastloan.mgt.application.base.model.ApplicationIPC;
import com.fastloan.mgt.application.base.model.ApplicationValue;
import com.fastloan.mgt.application.base.model.ApplicationVo;
import com.fastloan.mgt.application.base.service.ApplicationIPCService;
import com.fastloan.mgt.application.base.service.ApplicationService;
import com.fastloan.mgt.application.contract.dao.ApplicationLoanResultMapper;
import com.fastloan.mgt.application.contract.model.ApplicationContract;
import com.fastloan.mgt.application.contract.model.ApplicationLoanResult;
import com.fastloan.mgt.application.contract.service.ApplicationContractService;
import com.fastloan.mgt.application.contract.service.impl.loanmode.mode.ry.enmus.RyLoanStatusEnum;
import com.fastloan.mgt.customer.model.CustomerAmount;
import com.fastloan.mgt.customer.model.ZyCustomer;
import com.fastloan.mgt.customer.model.ZyCustomerCard;
import com.fastloan.mgt.customer.service.CustomerAmountService;
import com.fastloan.mgt.customer.service.ZyCustomerCardService;
import com.fastloan.mgt.customer.service.ZyCustomerService;
import com.fastloan.mgt.jx.model.ApplicationExtend;
import com.fastloan.mgt.customer.model.CustomerCredit;
import com.fastloan.mgt.jx.model.dto.*;
import com.fastloan.mgt.jx.model.vo.JxLoanResultVO;
import com.fastloan.mgt.jx.model.vo.JxModelResultVO;
import com.fastloan.mgt.jx.model.vo.OrderStatusVO;
import com.fastloan.mgt.jx.service.ApplicationExtendService;
import com.fastloan.mgt.customer.service.CustomerCreditService;
import com.fastloan.mgt.jx.service.JxService;
import com.fastloan.mgt.product.basics.model.Product;
import com.fastloan.mgt.product.basics.service.ProductService;
import com.fastloan.mgt.product.enums.ProductEnumSet;
import com.fastloan.safe.core.util.ManagerKit;
import com.fastloan.utils.DateTimeUtil;
import com.kawins.base.BaseMapper;
import com.kawins.base.baseabs.BaseServiceImpl;
import com.kawins.result.ResultTo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;

import static com.fastloan.common.model.CheckResultEnum.*;
import static com.fastloan.mgt.application.base.enums.ApplicationStatusEnum.*;
import static com.fastloan.mgt.application.base.enums.ApplicationStatusEnum.ORDER_CANCELLATION;
import static com.fastloan.mgt.customer.enums.CustomerAmountEnum.NIEZATWIERDZONY;
import static com.fastloan.mgt.customer.enums.CustomerAmountEnum.NORMALS;
import static com.fastloan.mgt.customer.enums.CustomerType.JX_CUSTOMER;
import static com.fastloan.mgt.jx.enums.CreditEnum.EVALUATING;
import static com.fastloan.mgt.jx.enums.CreditEnum.FINISH;
import static com.fastloan.mgt.jx.enums.CreditEnum.UNRECORDED;
import static com.fastloan.mgt.product.enums.ProductType.ADVANCE;
import static com.fastloan.mgt.product.enums.ProductType.SLG_SIM;
import static com.fastloan.utils.DateTimeUtil.NORM_DATETIME_PATTERN;
import static java.util.stream.Collectors.toList;

/**
 * 预授信service
 *
 * @author chenkai
 * createTime 2018-01-2018/1/5 9:48
 */
@Service
public class JxServiceImpl extends BaseServiceImpl<JxCreditDTO> implements JxService {
    @Autowired
    private ZyCustomerService customerService;

    @Autowired
    private ApplicationIPCService applicationIPCService;

    @Autowired
    private ZyCustomerCardService zyCustomerCardService;

    @Autowired
    private ApplicationService applicationService;

    @Autowired
    private CustomerAmountService customerAmountService;

    @Autowired
    private ApplicationContractService applicationContractService;

    @Autowired
    private ProductService productService;

    @Autowired
    private ApplicationExtendService applicationExtendService;

    @Autowired
    private CustomerCreditService customerCreditService;

    @Autowired
    private ApplicationLoanResultMapper applicationLoanResultMapper;

    private static final Map<Integer, String> map = new HashMap<Integer, String>() {
        {
            put(195, "country_id");
            put(196, "account_capital");
            put(197, "overseas");
            put(198, "store_sales");
            put(199, "store_qualifications");
            put(200, "store_capital");
            put(201, "order_history");
            put(202, "store_info");
            put(205, "order_historyIn");
            put(206, "address");
            put(207, "years");
            put(208, "email");
            put(209, "evaluation");
            put(210, "user_id");
            put(213, "order_status");
            put(214, "order_money");
            put(215, "store_id");
            put(216, "order_subscription");
            put(217, "order_time");
            put(218, "order_type");
            put(219, "order_good_info");
            put(220, "pick_up_goods");
//            put(221, "payee_bank_account");
//            put(222, "payee_bank_name");
//            put(223, "payee_bank_card");
        }
    };

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CheckResult preliminaryCredit(JxCreditDTO jxCreditDTO) {
        CompletableFuture<CheckResult> checkResultCompletableFuture
                = CompletableFuture.supplyAsync(() -> insertJxCustomer(jxCreditDTO));
        return checkResultCompletableFuture.join();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CheckResult customerIPC(String productId, String customerId) {
        List<ApplicationIPC> applicationIPCS = applicationIPCService.selectProductIPC(productId, 0);
        ZyCustomer customer = customerService.selectByPrimaryKey(customerId);
        if (customer == null || StringUtils.isBlank(customer.getTempValue())) {
            log.error("未获取到极鲜网客户信息");
            return CheckResult.fail(ILLEGAL_REQUEST.getMsg(), ILLEGAL_REQUEST.getCode());
        }
        String tempValue = customer.getTempValue();
        Map tempMap = JSON.parseObject(tempValue, Map.class);
        CompletableFuture<List<ApplicationIPC>> completableFuture
                = CompletableFuture.supplyAsync(() -> getApplicationIPCS(applicationIPCS, tempMap));
        List<ApplicationIPC> join = completableFuture.join();
        return CheckResult.success(join);
    }

    @Override
    public JxModelResultVO backModelResult(JxSeCreditDTO creditDTO) {
        JxModelResultVO jxModelResultVO = new JxModelResultVO();
        jxModelResultVO.setAgent_order_id(creditDTO.getAgent_id());
        jxModelResultVO.setStatus(UNRECORDED.getType());
        jxModelResultVO.setPass(false);
        CheckResult checkResult = queryAppIdByCardOrUserId(creditDTO.getCard_id(), creditDTO.getUser_id(), creditDTO.getAgent_id());
        if (!checkResult.isCheckResult()) {
            return jxModelResultVO;
        }
        Application application = (Application) checkResult.getData();
        if (application == null) {
            return jxModelResultVO;
        }
        ZyCustomer customer = customerService.selectByPrimaryKey(application.getCustomerId());
        if (customer == null) {
            return jxModelResultVO;
        }
        setJxModelResult(jxModelResultVO, application, customer);
        return jxModelResultVO;
    }

    /**
     * 预授信结果
     *
     * @param jxModelResultVO
     * @param application
     * @param customer
     */
    private void setJxModelResult(JxModelResultVO jxModelResultVO, Application application, ZyCustomer customer) {
        CustomerAmount customerAmount = new CustomerAmount();
        customerAmount.setProductId(application.getProductId());
        customerAmount.setCustomerId(application.getCustomerId());
        customerAmount.setStatus(NORMALS.getCode());
        CustomerAmount customerAmountTemp = customerAmountService.selectOne(customerAmount);
        jxModelResultVO.setCard_id(customer.getCardNum());
        jxModelResultVO.setOrder_id(application.getApplicationId());
        if (customerAmountTemp != null && customerAmountTemp.getStatus().equals(NORMALS.getCode())) {
            String creditLine = getBigDecimalString(customerAmountTemp.getOriginalAmount().subtract(customerAmountTemp.getCreditAmount()));
            String loanAmount = getBigDecimalString(customerAmountTemp.getOriginalAmount());
            jxModelResultVO.setCredit_line(creditLine);
            jxModelResultVO.setPass(true);
            jxModelResultVO.setStatus(FINISH.getType());
            jxModelResultVO.setPre_credit(loanAmount);
            jxModelResultVO.setDead_line(DateTimeUtil.dateToString(customerAmountTemp.getDeadLine(), NORM_DATETIME_PATTERN));
        } else if (customerAmountTemp != null && customerAmountTemp.getStatus().equals(NIEZATWIERDZONY.getCode())) {
            jxModelResultVO.setStatus(EVALUATING.getType());
        } else {
            jxModelResultVO.setStatus(FINISH.getType());
        }
    }


    private String getBigDecimalString(BigDecimal creditAmount) {
        if (creditAmount != null && creditAmount.compareTo(BigDecimal.ZERO) > 0) {
            DecimalFormat decimalFormat = new DecimalFormat("#.0000");
            return decimalFormat.format(creditAmount.setScale(4, BigDecimal.ROUND_UP));
        }
        return "0.0000";
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CheckResult submitCreditApplication(ApplicationVo applicationVo, CustomerCredit customerCredit, String agentOrderId) {
        //验证流水号是否申请过进件
        CheckResult checkResult = queryCreditApplicationIdByAgentOrderId(agentOrderId);
        if (checkResult.isCheckResult()) {
            return CheckResult.fail(SERIAL_NUMBER_ALREADY.getMsg(), SERIAL_NUMBER_ALREADY.getCode());
        }
        Product product = productService.selectByPrimaryKey(applicationVo.getProductId());
        //验证产品是否为预授信产品
        if (!product.getProductType().equals(ADVANCE.getType())) {
            return CheckResult.fail(ILLEGAL_REQUEST.getMsg(), ILLEGAL_REQUEST.getCode());
        }
        String customerId = applicationVo.getCustomerId();
        customerCredit.setCustomerId(applicationVo.getCustomerId());
        //更新人行征信信息
        CustomerCredit customerCreditTemp = customerCreditService.selectByPrimaryKey(applicationVo.getCustomerId());
        if (customerCreditTemp != null) {
            customerCreditService.updateByPrimaryKeySelective(customerCredit);
        } else {
            customerCreditService.insertSelective(customerCredit);
        }
        Integer integer = customerAmountService.queryIfCredit(applicationVo.getCustomerId());
        //已存在预授信信息
        if (integer != null && integer > 0) {
            return CheckResult.fail(CUSTOMER_INFO_ALREADY_CREDIT.getMsg(), CUSTOMER_INFO_ALREADY_CREDIT.getCode());
        }
        return applyApplication(applicationVo, customerId, agentOrderId);
    }

    private CheckResult applyApplication(ApplicationVo applicationVo, String customerId, String agentOrderId) {
        ZyCustomer customer = customerService.selectByPrimaryKey(customerId);
        JxCreditDTO jxCreditDTO = JSON.parseObject(customer.getTempValue(), JxCreditDTO.class);
        ResultTo resultTo = applicationService.submitApplication(applicationVo);
        Object obj = resultTo.get("applicationId");
        if (obj == null) {
            String message = resultTo.get("message").toString();
            return CheckResult.fail(message, PARAMETER_ERROR);
        }
        String applicationId = obj.toString();
        insertApplicationExtend(agentOrderId, applicationId, 1);
        return CheckResult.success(jxCreditDTO.getComeback_url());
    }

    @Override
    @Transactional
    public CheckResult submitJxApplication(ApplicationVo applicationVo, String agentOrderId) {
        //验证流水号是否申请过进件
        CheckResult checkResult = queryApplicationIdByAgentOrderId(agentOrderId);
        if (checkResult.isCheckResult()) {
            return CheckResult.fail(SERIAL_NUMBER_ALREADY.getMsg(), SERIAL_NUMBER_ALREADY.getCode());
        }
        //客户是否申请过预授信
        Integer integer = customerAmountService.queryIfCredit(applicationVo.getCustomerId());
        if (integer != null && integer == 0) {
            return CheckResult.fail(NOT_CREDIT.getMsg(), NOT_CREDIT.getCode());
        }
        //预授信额度是否足够
        CheckResult checkResult2
                = customerAmountService.verifyApplyAmount(applicationVo.getCustomerId(), applicationVo.getProductId(), applicationVo.getApplyAmount());
        if (!checkResult2.isCheckResult()) {
            return CheckResult.fail(LINE_CREDIT_INSUFFICIENT.getMsg(), LINE_CREDIT_INSUFFICIENT.getCode());
        }
        ResultTo resultTo = applicationService.submitApplication(applicationVo);
        Object obj = resultTo.get("applicationId");
        if (obj == null) {
            String message = resultTo.get("message").toString();
            return CheckResult.fail(message, PARAMETER_ERROR);
        }
        String applicationId = obj.toString();
        String creditApplicationId = customerService.queryCreditApplicationIdByCustomer(resultTo.get("applicationId").toString());
        if (!StringUtils.isBlank(creditApplicationId)) {
            customerAmountService.changeCreditAmount(creditApplicationId, applicationVo.getApplyAmount());
        }
        //插入进件流水号
        insertApplicationExtend(agentOrderId, applicationId, 0);
        ZyCustomer customer = customerService.selectByPrimaryKey(applicationVo.getCustomerId());
        JxLoanDTO loanDTO = JSON.parseObject(customer.getTempValue(), JxLoanDTO.class);
        return CheckResult.success(loanDTO.getComeback_url());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CheckResult applyApplication(JxLoanDTO jxLoanDTO) {
        CompletableFuture<CheckResult> checkResultCompletableFuture
                = CompletableFuture.supplyAsync(() -> insertJxCustomer(jxLoanDTO));
        return checkResultCompletableFuture.join();
    }

    @Override
    public CheckResult backLoanResult(String applicationId) {
        Application application = applicationService.selectByPrimaryKey(applicationId);
        ApplicationContract contractInfo = applicationContractService.getContractInfo(applicationId);
        Product product = productService.selectByPrimaryKey(application.getProductId());
        ZyCustomer customer = customerService.selectByPrimaryKey(application.getCustomerId());
        String tempValue = customer.getTempValue();
        JxLoanDTO jxLoanDTO = JSON.parseObject(tempValue, JxLoanDTO.class);
        JxLoanResultVO jxLoanResultVO = new JxLoanResultVO();
        if (jxLoanDTO != null) {
            jxLoanResultVO.setOrder_id(applicationId);
            jxLoanResultVO.setAgent_order_id(jxLoanDTO.getAgent_order_id());
            ApplicationLoanResult applicationLoanResult = applicationLoanResultMapper.selectByPrimaryKey(applicationId);
            jxLoanResultVO.setRemit_result(RyLoanStatusEnum.getByStatus(applicationLoanResult.getLoanStatus()).name());
            jxLoanResultVO.setRemit_time(DateTimeUtil.format(applicationLoanResult.getLoanTime(), NORM_DATETIME_PATTERN));
            jxLoanResultVO.setContract_no(contractInfo.getContractNo());
            jxLoanResultVO.setProduct(product.getProductName());
            String loanAmount = getBigDecimalString(contractInfo.getLoanAmount());
            jxLoanResultVO.setMoney(loanAmount);
            jxLoanResultVO.setLimit_time(contractInfo.getCreditPeriod().toString());
            jxLoanResultVO.setRepay_way(product.getRepayment().toString());
            jxLoanResultVO.setRate(contractInfo.getLoanMonthRate().toString());
            jxLoanResultVO.setDeadline(DateTimeUtil.addMonth(contractInfo.getLoanTime(), contractInfo.getCreditPeriod()).toString());
        }
        Map<String, Object> map = new HashMap<>();
        map.put("jxLoanResultVO", jxLoanResultVO);
        map.put("jxLoanDTO", jxLoanDTO);
        return CheckResult.success(map);
    }

    @Override
    public CheckResult queryAppIdByCardId(JxSeCreditDTO jxSeCreditDTO) {
        CheckResult checkResult = queryApplicationIdByAgentOrderId(jxSeCreditDTO.getAgent_id());
        if (!checkResult.isCheckResult()) {
            return checkResult;
        }
        String applicationId = checkResult.getData().toString();
        Application application = applicationService.selectByPrimaryKey(applicationId);
        return CheckResult.success("/#/loan/result/" + application.getApplicationId());
    }

    @Override
    public String insertCustomerAV(String customerId, JxAvInfoDTO jxAvInfoDTO) {
        ZyCustomer customer = customerService.selectByPrimaryKey(customerId);
        customer.setAvValue(JSON.toJSONString(jxAvInfoDTO));
        customerService.updateByPrimaryKeySelective(customer);
        return customerId;
    }

    @Override
    public CheckResult insertProduct(Product product, MultipartFile[] file) {
        Product productTemp = new Product();
        productTemp.setOrgId(ManagerKit.getOrgId());
        if (product.getProductType() != null && product.getProductType().equals(ADVANCE.getType())) {
            productTemp.setProductType(product.getProductType());
        }
        productTemp = productService.selectOne(productTemp);
        if (productTemp != null) {
            return CheckResult.fail("无法重复申请预授信产品");
        }
        return CheckResult.success(productService.createProduct(product, file));
    }

    @Override
    public CheckResult queryLoanResult(JxApplicationStateDTO applicationStateDTO) {
        CheckResult checkResult = queryApplicationIdByAgentOrderId(applicationStateDTO.getAgent_order_id());
        if (!checkResult.isCheckResult()) {
            return checkResult;
        }
        String applicationId = checkResult.getData().toString();
        OrderStatusVO orderStatusVO = new OrderStatusVO();
        Application application = applicationService.selectByPrimaryKey(applicationId);
        switch (ApplicationStatusEnum.getByType(application.getApplicationStatus())) {
            case APP_LENDING:
                orderStatusVO.setOrder_status(0);
                break;
            case WAIT_REPAYMENT:
                orderStatusVO.setOrder_status(1);
                break;
            case ORDER_CANCELLATION:
                orderStatusVO.setOrder_status(2);
                break;
            case LOAN_FAIL:
                orderStatusVO.setOrder_status(3);
                break;
            case LOAN_REJECT:
                orderStatusVO.setOrder_status(5);
                break;
            default:
                orderStatusVO.setOrder_status(4);
        }
        if (applicationStateDTO.getOrder_status().equals(1) && application.getApplicationStatus().equals(WAIT_AFFIRM.getType())) {
            application.setApplicationStatus(WAIT_SIGNED.getType());
            applicationService.updateByPrimaryKeySelective(application);
            orderStatusVO.setOrder_status(0);
        } else if (applicationStateDTO.getOrder_status().equals(0) && application.getApplicationStatus().equals(WAIT_AFFIRM.getType())) {
            application.setApplicationStatus(ORDER_CANCELLATION.getType());
            applicationService.updateByPrimaryKeySelective(application);
            orderStatusVO.setOrder_status(2);
        }
        return CheckResult.success(orderStatusVO);
    }

    @Override
    public CheckResult queryAppIdByCardOrUserId(String cardId, String userId, String agentId) {
        ZyCustomer customerTemp = new ZyCustomer();
        customerTemp = getZyCustomer(cardId, userId, customerTemp);
        if (customerTemp == null) {
            return CheckResult.fail(NOT_CHECKED.getMsg(), NOT_CHECKED.getCode());
        }
        Product product = new Product();
        product.setProductType(2);
        product.setAgentId(agentId);
        product = productService.selectOne(product);
        Application application = new Application();
        if (product != null) {
            application.setCustomerId(customerTemp.getId());
            application.setProductId(product.getProductId());
            application = applicationService.selectOne(application);
        } else {
            return CheckResult.fail(NOT_CHECKED.getMsg(), NOT_CHECKED.getCode());
        }
        return CheckResult.success(application);
    }

    @Override
    public CheckResult offlineCreditApplication(JxCreditDTO jxCreditDTO, BigDecimal creditAmount, CustomerCredit customerCredit) {
        //插入更新预授信信息
        CheckResult checkResult = queryCreditApplicationIdByAgentOrderId(jxCreditDTO.getAgent_order_id());
        if (checkResult.isCheckResult()) {
            return CheckResult.fail(SERIAL_NUMBER_ALREADY.getMsg(), SERIAL_NUMBER_ALREADY.getCode());
        }
        Product product = new Product();
        product.setAgentId(jxCreditDTO.getAgent_id());
        product.setProductType(ADVANCE.getType());
        product = productService.selectOne(product);
        if (product == null) {
            log.info("未查询到对应产品");
            return CheckResult.fail(ILLEGAL_REQUEST.getMsg(), ILLEGAL_REQUEST.getCode());
        }
        log.debug("收到客户数据: ", jxCreditDTO.toString());
        ZyCustomer customer = setZyCustomer(jxCreditDTO.getCard_id(), jxCreditDTO.getName(), jxCreditDTO.getPhone(), JSON.toJSONString(jxCreditDTO));
        String customerId = insertOrUpdateCustomer(jxCreditDTO.getCard_id(), jxCreditDTO.getBank_id(), customer, jxCreditDTO.getUser_id());
        startCredit(customerId, product, jxCreditDTO.getAgent_order_id(), creditAmount, customerCredit);
        return CheckResult.success();
    }

    @Override
    protected BaseMapper<JxCreditDTO> buildDao() {
        return null;
    }

    /**
     * 插入ipc信息
     *
     * @param applicationIPCS
     * @param tempMap
     * @return
     */
    private List<ApplicationIPC> getApplicationIPCS(List<ApplicationIPC> applicationIPCS, Map tempMap) {
        return applicationIPCS.stream()
                .peek(applicationIPC -> applicationIPC.getChildList()
                        .forEach(ipc -> {
                            String name = map.get(ipc.getCode());
                            if (name != null && !StringUtils.isBlank(name) && tempMap.get(name) != null) {
                                try {
                                    BeanUtils.setProperty(ipc, "applicationValue", tempMap.get(name));
                                    log.debug("IPC赋值成功, IPC: {}, 值: {}", ipc.getName(), tempMap.get(name));
                                } catch (IllegalAccessException | InvocationTargetException e) {
                                    e.printStackTrace();
                                    log.error("IPC赋值失败, IPC: {}, 值: {}, 失败原因{}", ipc.getName(), tempMap.get(name), e.getMessage());
                                }
                            }
                        }))
                .collect(toList());
    }

    /**
     * 插入极鲜网用户信息(预授信)
     *
     * @param jxCreditDTO
     */
    private CheckResult insertJxCustomer(JxCreditDTO jxCreditDTO) {
        //验证流水号是否申请过预授信
        CheckResult checkResult = queryCreditApplicationIdByAgentOrderId(jxCreditDTO.getAgent_order_id());
        if (checkResult.isCheckResult()) {
            return CheckResult.fail(SERIAL_NUMBER_ALREADY.getMsg(), SERIAL_NUMBER_ALREADY.getCode());
        }
        Product product = new Product();
        product.setAgentId(jxCreditDTO.getAgent_id());
        product.setProductType(ADVANCE.getType());
        product = productService.selectOne(product);
        if (product == null) {
            log.info("未查询到对应产品");
            return CheckResult.fail(ILLEGAL_REQUEST.getMsg(), ILLEGAL_REQUEST.getCode());
        }
        log.debug("收到客户数据: ", jxCreditDTO.toString());
        ZyCustomer customer = setZyCustomer(jxCreditDTO.getCard_id(), jxCreditDTO.getName(), jxCreditDTO.getPhone(), JSON.toJSONString(jxCreditDTO));
        String customerId = insertOrUpdateCustomer(jxCreditDTO.getCard_id(), jxCreditDTO.getBank_id(), customer, jxCreditDTO.getUser_id());
        log.debug("插入(更新)极鲜网银行卡:{}, 客户id:{}: ", jxCreditDTO.getBank_id(), customerId);
        return CheckResult.success("/#/fresh/credit/" + customerId + "/" + jxCreditDTO.getAgent_order_id() + "/" + product.getProductId());
    }

    /**
     * 执行进件申请
     *
     * @param jxLoanDTO
     * @return
     */
    private CheckResult insertJxCustomer(JxLoanDTO jxLoanDTO) {
        //验证流水号是否申请过进件
        CheckResult checkResult = queryApplicationIdByAgentOrderId(jxLoanDTO.getAgent_order_id());
        if (checkResult.isCheckResult()) {
            return CheckResult.fail(SERIAL_NUMBER_ALREADY.getMsg(), SERIAL_NUMBER_ALREADY.getCode());
        }
        Product product = new Product();
        product.setAgentId(jxLoanDTO.getAgent_id());
        product.setProductType(SLG_SIM.getType());
        product = productService.selectOne(product);
        if (product == null) {
            log.info("未查询到对应产品");
            return CheckResult.fail(ILLEGAL_REQUEST.getMsg(), ILLEGAL_REQUEST.getCode());
        }
        ZyCustomer customer = setZyCustomer(jxLoanDTO.getCard_id(), jxLoanDTO.getName(), jxLoanDTO.getPhone(), JSON.toJSONString(jxLoanDTO));
        String customerId = insertOrUpdateCustomer(jxLoanDTO.getCard_id(), jxLoanDTO.getBank_id(), customer, jxLoanDTO.getUser_id());
        //客户是否申请过预授信
        Integer integer = customerAmountService.queryIfCredit(customerId);
        //未进行预授信
        if (integer != null && integer == 0) {
            return CheckResult.fail(NOT_CREDIT.getMsg(), NOT_CREDIT.getCode());
        }
        return CheckResult.success("/#/fresh/loan/" + customerId + "/" + product.getProductId() + "/" + jxLoanDTO.getAgent_order_id());
    }

    /**
     * 插入进件流水号
     *
     * @param agentOrderId
     * @param applicationId
     * @param type
     */
    private void insertApplicationExtend(String agentOrderId, String applicationId, int type) {
        ApplicationExtend applicationExtend = new ApplicationExtend();
        applicationExtend.setAgentOrderId(agentOrderId);
        applicationExtend.setApplicationId(applicationId);
        applicationExtend.setAppType(type);
        applicationExtendService.insert(applicationExtend);
    }

    /**
     * 预授信进件申请(线下)
     *
     * @param creditAmount
     * @param product
     * @param customerId
     * @param checkResult1
     * @return
     */
    private String applyApplication(BigDecimal creditAmount, Product product, String customerId, CheckResult checkResult1) {
        List<ApplicationValue> applicationIPCS = getApplicationIPCS((List<ApplicationIPC>) checkResult1.getData());
        String ipcValue = JSON.toJSONString(applicationIPCS);
        ApplicationVo applicationVo = new ApplicationVo();
        applicationVo.setIpcValue(ipcValue);
        applicationVo.setApplyAmount(creditAmount);
        applicationVo.setCustomerId(customerId);
        applicationVo.setProductId(product.getProductId());
        applicationVo.setOrgId(product.getOrgId());
        applicationVo.setApplyPeriod(product.getTimeLimit());
        applicationVo.setApplyTime(new Date());
        applicationVo.setCreateTime(new Date());
        ResultTo resultTo = applicationService.submitApplication(applicationVo);
        Object obj = resultTo.get("applicationId");
        if (obj != null) {
            return obj.toString();
        }
        return null;
    }

    /**
     * 生成ipc数据
     *
     * @param applicationIPCList
     * @return
     */
    private List<ApplicationValue> getApplicationIPCS(List<ApplicationIPC> applicationIPCList) {
        List<ApplicationValue> applicationValueList = new ArrayList<>();
        for (ApplicationIPC applicationIPC : applicationIPCList) {
            ApplicationValue applicationValue = new ApplicationValue();
            applicationValue.setProductTempId(applicationIPC.getProductTempId());
            applicationValueList.add(applicationValue);
            applicationIPC.getChildList().forEach(applicationIPC1 -> {
                        ApplicationValue applicationValue1 = new ApplicationValue();
                        applicationValue1.setProductTempId(applicationIPC1.getProductTempId());
                        applicationValue1.setApplicationValue(applicationIPC1.getApplicationValue());
                        applicationValueList.add(applicationValue1);
                    }
            );
        }
        return applicationValueList;
    }

    /**
     * 自动授信(线下)
     *
     * @param customerId
     * @param product
     * @param agentOrderId
     * @param creditAmount
     * @param customerCredit
     */
    private CheckResult startCredit(String customerId, Product product, String agentOrderId, BigDecimal creditAmount, CustomerCredit customerCredit) {
        Integer integer = customerAmountService.queryIfCredit(customerId);
        //已存在预授信信息
        if (integer != null && integer > 0) {
            return CheckResult.fail(CUSTOMER_INFO_ALREADY_CREDIT.getMsg(), CUSTOMER_INFO_ALREADY_CREDIT.getCode());
        }
        CheckResult checkResult1 = customerIPC(product.getProductId(), customerId);
        if (checkResult1.isCheckResult()) {
            String applicationId = applyApplication(creditAmount, product, customerId, checkResult1);
            if (!StringUtils.isBlank(applicationId)) {
                Application application = applicationService.selectByPrimaryKey(applicationId);
                application.setApplicationStatus(PRELIMINARY_CREDIT_PASS.getType());
                applicationService.updateByPrimaryKeySelective(application);
                customerCredit.setCustomerId(customerId);
                CustomerCredit customerCreditTemp = customerCreditService.selectByPrimaryKey(customerId);
                if (customerCreditTemp != null) {
                    customerCreditService.updateByPrimaryKeySelective(customerCredit);
                } else {
                    customerCreditService.insertSelective(customerCredit);
                }
                CustomerAmount customerAmount = new CustomerAmount();
                customerAmount.setCustomerId(customerId);
                customerAmount.setProductId(product.getProductId());
                customerAmount.setCreditAmount(creditAmount);
                customerAmount.setOriginalAmount(creditAmount);
                customerAmount.setStatus(1);
                customerAmount.setCreateTime(new Date());
                customerAmount.setApplicationId(applicationId);
                Calendar cal = Calendar.getInstance();
                cal.add(Calendar.MONTH, 6);
                customerAmount.setDeadLine(cal.getTime());
                customerAmountService.insert(customerAmount);
                insertApplicationExtend(agentOrderId, applicationId, 0);
                return CheckResult.success();
            }
        }
        return CheckResult.fail(INTERNAL_ERROR.getMsg(), INTERNAL_ERROR.getCode());
    }


    /**
     * 设置极鲜网客户信息
     *
     * @param card_id
     * @param name
     * @param phone
     * @param tempValue
     * @return
     */
    private ZyCustomer setZyCustomer(String card_id, String name, String phone, String tempValue) {
        ZyCustomer customer = new ZyCustomer();
        if (card_id != null) {
            customer.setCardNum(card_id);
        }
        if (name != null) {
            customer.setCname(name);
        }
        if (phone != null) {
            customer.setPhoneNum(phone);
        }
        customer.setTempValue(tempValue);
        customer.setCreateTime(new Date());
        customer.setVerify(0);
        customer.setStatus(JX_CUSTOMER.getCode());
        return customer;
    }

    /**
     * 插入更新极鲜网用户信息
     *
     * @param cardId
     * @param bankId
     * @param customer
     * @param userId
     */
    private String insertOrUpdateCustomer(String cardId, String bankId, ZyCustomer customer, String userId) {
        ZyCustomer customerTemp = new ZyCustomer();
        customerTemp = getZyCustomer(cardId, userId, customerTemp);
        if (customerTemp != null) {
            customer.setId(customerTemp.getId());
            log.debug("更新极鲜网客户id:{}: ", customer.getId());
            customerService.updateByPrimaryKeySelective(customer);
        } else {
            log.debug("插入极鲜网客户id:{}: ", customer.getId());
            customerService.insertSelective(customer);
        }
        if (!StringUtils.isBlank(bankId) && StringUtils.isBlank(customer.getId())) {
            ZyCustomerCard zyCustomerCard = new ZyCustomerCard();
            zyCustomerCard.setCustomerId(customer.getId());
            zyCustomerCard.setCardNum(bankId);
            ZyCustomerCard zyCustomerCardTemp = new ZyCustomerCard();
            zyCustomerCardTemp.setCustomerId(customer.getId());
            zyCustomerCardTemp = zyCustomerCardService.selectOne(zyCustomerCardTemp);
            if (zyCustomerCardTemp != null) {
                log.debug("更新极鲜网银行卡信息, 客户id:{}:, 卡片id{} ", customer.getId(), bankId);
                zyCustomerCardService.updateByPrimaryKeySelective(zyCustomerCard);
            } else {
                log.debug("插入极鲜网银行卡信息, 客户id:{}:, 卡片id{} ", customer.getId(), bankId);
                zyCustomerCardService.insert(zyCustomerCard);
            }
        }
        return customer.getId();
    }

    private ZyCustomer getZyCustomer(String cardId, String userId, ZyCustomer customerTemp) {
        if (!StringUtils.isBlank(cardId)) {
            customerTemp.setCardNum(cardId);
            customerTemp = customerService.selectOne(customerTemp);
        } else if (!StringUtils.isBlank(userId)) {
            customerTemp = customerService.queryJxUserID(userId);
        }
        return customerTemp;
    }


    /**
     * 根据流水号查询进件id
     *
     * @param agentOrderId
     * @return
     */
    private CheckResult queryApplicationIdByAgentOrderId(String agentOrderId) {
        ApplicationExtend applicationExtend = new ApplicationExtend();
        applicationExtend.setAgentOrderId(agentOrderId);
        applicationExtend.setAppType(0);
        ApplicationExtend applicationExtendTemp = applicationExtendService.selectOne(applicationExtend);
        if (applicationExtendTemp != null) {
            return CheckResult.success(applicationExtendTemp.getApplicationId());
        }
        return CheckResult.fail(CheckResultEnum.SERIAL_NUMBER_NONENTITY.getMsg(), CheckResultEnum.SERIAL_NUMBER_NONENTITY.getCode());
    }

    /**
     * 根据预授信流水号查询进件id
     *
     * @param agentOrderId
     * @return
     */
    private CheckResult queryCreditApplicationIdByAgentOrderId(String agentOrderId) {
        ApplicationExtend applicationExtend = new ApplicationExtend();
        applicationExtend.setAgentOrderId(agentOrderId);
        applicationExtend.setAppType(1);
        ApplicationExtend applicationExtendTemp = applicationExtendService.selectOne(applicationExtend);
        if (applicationExtendTemp != null) {
            return CheckResult.success(applicationExtendTemp.getApplicationId());
        }
        return CheckResult.fail(CheckResultEnum.SERIAL_NUMBER_NONENTITY.getMsg(), CheckResultEnum.SERIAL_NUMBER_NONENTITY.getCode());
    }


}
